package withdrawalhandler

import (
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"log"
	"time"
	"yundian/internel/app/dao"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/models/cashlog"
	"yundian/internel/pkg/authorized"
	"yundian/internel/pkg/dingo"
	. "yundian/internel/pkg/dingo/result"
)

func HandleAddBillWithdrawal(c *gin.Context) {
	withdrawalModel := &request.AddBillWithdrawalReq{}
	dingo.ErrorIf(c.ShouldBindJSON(withdrawalModel)).Unwrap()
	userId := withdrawalModel.UserId

	parentId, _ := helper.GetParentIdFromCtx(c)
	isAdmin, _ := helper.GetIsAdminFromCtx(c)

	if isAdmin != helper.TypeNumIsAdminOperator && !helper.IsAdminAndStaff(isAdmin, parentId) {
		Response(c)("", CodeNoMethod, false)(OK)
		return
	}

	//校验参数
	if withdrawalModel.Money == 0 || withdrawalModel.TransferMoney == 0 {
		Response(c)("请求参数错误", CodeInvalidParam, false)(OK)
		return
	}

	// 校验提现金额
	// 计算已提现金额(处理成功的)
	cashTotal := dao.NewOrderDao().GetCashLogByUserId(userId).Unwrap().(int64)
	log.Println("打印测试数据--已提现金额", cashTotal)

	// 计算分红总金额
	dividTotal := dao.NewOrderDao().GetDividendsMoneyByUserId(userId).Unwrap().(int64)
	log.Println("打印测试数据--分红总金额", dividTotal)

	// 总分红 - 已提现 = 可提现金额
	cashMoney := decimal.NewFromInt(dividTotal).Sub(decimal.NewFromInt(cashTotal)).IntPart()
	log.Println("打印测试数据--可提现金额", cashMoney)

	if withdrawalModel.Money > cashMoney {
		Response(c)("提现金额不能大于可提现金额", CodeInvalidParam, false)(BadRequest)
		return
	}

	//判断是否存在未处理的订单
	cashLogInfo := dao.NewOrderDao().GetCashLogByInfo(userId).Unwrap().(cashlog.CashLogModel)
	if cashLogInfo.ID > 0 {
		Response(c)("存在有未处理订单", CodeSuccess, false)(BadRequest)
		return
	}

	//入库
	cashLogModel := cashlog.CashLogModel{}
	//业务参数
	cashLogModel.UserID = userId
	cashLogModel.Money = withdrawalModel.Money
	cashLogModel.TransferMoney = withdrawalModel.TransferMoney
	cashLogModel.ServiceCharge = withdrawalModel.ServiceCharge

	cashLogModel.MoneyStr = decimal.NewFromInt(withdrawalModel.Money).Div(decimal.NewFromInt(100)).StringFixed(2)
	cashLogModel.TransferMoney = withdrawalModel.Money
	cashLogModel.TransferMoneyStr = decimal.NewFromInt(withdrawalModel.Money).Div(decimal.NewFromInt(100)).StringFixed(2)
	cashLogModel.TransferType = 3 // 线下结算
	cashLogModel.OperateNote = withdrawalModel.OperateNote
	cashLogModel.Desc = withdrawalModel.OperateNote

	cashLogModel.CreateAt = dingo.Time(time.Now().Unix())
	cashLogModel.TradeNo = authorized.GetRandomString(32)
	cashLogModel.State = 2
	cashLogModel.VerifyStatus = 2

	insertState := dao.NewCashDao().InsertTxCashLog(&cashLogModel).Unwrap().(bool)
	if !insertState {
		Response(c)("提现请求提交失败", CodeError, false)(Error)
		return
	}
	Response(c)("提现请求提交成功", CodeInsertSuccess, true)(OK)
	return
}

func HandleGetCashMoney(ctx *gin.Context) {
	param := &request.GetCashMoneyReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()
	userId := param.UserId

	// 计算已提现金额(处理成功的)
	cashTotal := dao.NewOrderDao().GetCashLogByUserId(userId).Unwrap().(int64)
	log.Println("打印测试数据--已提现金额", cashTotal)

	// 计算分红总金额
	dividTotal := dao.NewOrderDao().GetDividendsMoneyByUserId(userId).Unwrap().(int64)
	log.Println("打印测试数据--分红总金额", dividTotal)

	// 当天分红金额
	nowDividTotal := dao.NewOrderDao().GetTodayDividendsMoneyByUserId(userId).Unwrap().(int64)
	log.Println("打印测试数据--当天分红金额", nowDividTotal)

	// 总分红 - 已提现 = 可提现金额
	cashMoney := decimal.NewFromInt(dividTotal).Sub(decimal.NewFromInt(cashTotal))
	log.Println("打印测试数据--可提现金额", cashMoney)

	//c, _ := decimal.NewFromInt(dividTotal).Sub(decimal.NewFromInt(cashTotal)).Float64()
	//
	//if c < float64(0) {
	//	// 提现的金额    大于   订单分红金额  ---- 数据异常
	//
	//}

	// 可提现金额 = 分红总金额 - 已提现金额
	Response(ctx)("", CodeSuccess, &struct {
		CashTotal  string `json:"cashTotal"`  // 已提现金额
		DividTotal string `json:"dividTotal"` // 分红总额
		CashMoney  string `json:"cashMoney"`  // 可提现
		//NowDividTotal string `json:"nowDividTotal"` // 当天收益
	}{
		CashTotal:  decimal.NewFromInt(cashTotal).Div(decimal.NewFromFloat(100)).StringFixed(2),
		DividTotal: decimal.NewFromInt(dividTotal).Div(decimal.NewFromFloat(100)).StringFixed(2),
		//CashMoney:     cashMoney.Div(decimal.NewFromFloat(100)).StringFixed(2),
		CashMoney: cashMoney.Div(decimal.NewFromInt(100)).StringFixed(2),
		//NowDividTotal: decimal.NewFromInt(nowDividTotal).Div(decimal.NewFromFloat(100)).StringFixed(2),
	})(OK)
}

// HandleGetServiceOrderCashList 查询服务订单提现列表
func HandleGetServiceOrderCashList(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	param := &request.GetOrdersCashListReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()
	param.LoginUserId = userId
	param.IsAdmin, _ = helper.GetIsAdminFromCtx(ctx)
	data := dao.NewCashDao().GetServiceOrderCashList(param)

	Response(ctx)("", CodeSuccess, ResponseList{
		PageNo:     param.PageNo,
		PageSize:   param.PageSize,
		TotalCount: data.Val().(int64),
		TotalPage:  (data.Val().(int64) + int64(param.PageSize) - 1) / int64(param.PageSize),
		Data:       data.Unwrap(),
	})(OK)
}

// HandleVerifyServiceOrder 服务订单提现审核
func HandleVerifyServiceOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	paramData := &cashlog.CashOrderLogDb{}
	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(paramData)).Unwrap()
	param.Db = paramData
	param.UserId = userId

	param.IsAdmin, _ = helper.GetIsAdminFromCtx(ctx)
	param.ParentId, _ = helper.GetParentIdFromCtx(ctx)
	if param.IsAdmin != helper.TypeNumIsAdminOperator && !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		Response(ctx)("", CodeInvalidParam, false)(OK)
		return
	}

	if data := dao.NewCashDao().VerifyServiceOrder(param); data.Err != nil {
		Response(ctx)("", CodeInternalServerError, false)(OK)
		return
	}

	Response(ctx)("", CodeSuccess, true)(OK)
}

// HandleApplyServiceGoodsOrder 服务订单提现申请
func HandleApplyServiceGoodsOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	paramData := &cashlog.CashOrderLogDb{}
	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(paramData)).Unwrap()
	param.Db = paramData
	param.UserId = userId
	param.Db.OrderType = helper.TypeNumCashOrderLogOrderTypeGoods

	if data := dao.NewCashDao().ApplyServiceOrder(param); data.Err != nil {
		Response(ctx)("", CodeInternalServerError, false)(OK)
		return
	} else if data.Unwrap().(string) == "exist" {
		Response(ctx)("您有一笔提现，正在处理中...", CodeInvalidParam, false)(OK)
		return
	} else if data.Unwrap().(string) == "money" {
		Response(ctx)("提现金额错误", CodeInvalidParam, false)(OK)
		return
	}

	Response(ctx)("", CodeSuccess, true)(OK)
}

// HandleApplyServiceAutomateOrder 服务订单提现申请
func HandleApplyServiceAutomateOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	paramData := &cashlog.CashOrderLogDb{}
	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(paramData)).Unwrap()
	param.Db = paramData
	param.UserId = userId
	param.Db.OrderType = helper.TypeNumCashOrderLogOrderTypeAutomate

	if data := dao.NewCashDao().ApplyServiceOrder(param); data.Err != nil {
		Response(ctx)("", CodeInternalServerError, false)(OK)
		return
	} else if data.Unwrap().(string) == "exist" {
		Response(ctx)("您有一笔提现，正在处理中...", CodeInvalidParam, false)(OK)
		return
	} else if data.Unwrap().(string) == "money" {
		Response(ctx)("提现金额错误", CodeInvalidParam, false)(OK)
		return
	}

	Response(ctx)("", CodeSuccess, true)(OK)
}

// HandleApplyServiceRoomOrder 服务订单提现申请
func HandleApplyServiceRoomOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	paramData := &cashlog.CashOrderLogDb{}
	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(paramData)).Unwrap()
	param.Db = paramData
	param.UserId = userId
	param.Db.OrderType = helper.TypeNumCashOrderLogOrderTypeRoom

	if data := dao.NewCashDao().ApplyServiceOrder(param); data.Err != nil {
		Response(ctx)("", CodeInternalServerError, false)(OK)
		return
	} else if data.Unwrap().(string) == "exist" {
		Response(ctx)("您有一笔提现，正在处理中...", CodeInvalidParam, false)(OK)
		return
	} else if data.Unwrap().(string) == "money" {
		Response(ctx)("提现金额错误", CodeInvalidParam, false)(OK)
		return
	}

	Response(ctx)("", CodeSuccess, true)(OK)
}

// HandleApplyServiceOrder 服务订单提现申请
func HandleApplyServiceOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	paramData := &cashlog.CashOrderLogDb{}
	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(paramData)).Unwrap()
	param.Db = paramData
	param.UserId = userId

	if data := dao.NewCashDao().ApplyServiceOrder(param); data.Err != nil {
		Response(ctx)("", CodeInternalServerError, false)(OK)
		return
	} else if data.Unwrap().(string) == "exist" {
		Response(ctx)("您有一笔提现，正在处理中...", CodeInvalidParam, false)(OK)
		return
	} else if data.Unwrap().(string) == "money" {
		Response(ctx)("提现金额错误", CodeInvalidParam, false)(OK)
		return
	}

	Response(ctx)("", CodeSuccess, true)(OK)
}

// HandleGetServiceAutomateOrderMoney 查询服务订单可提现金额
func HandleGetServiceAutomateOrderMoney(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()
	param.UserId = userId
	param.Db = &cashlog.CashOrderLogDb{OrderType: helper.TypeNumCashOrderLogOrderTypeAutomate}

	automateData := dao.NewAutomateDaoDao().GetAutomateOrdersToCashByUserId(param).Unwrap().(*request.OrdersCashRes)
	cashNum := dao.NewCashDao().GetOrderCashNum(param).Unwrap().(int64)

	Response(ctx)("", CodeSuccess, map[string]interface{}{
		"cash":         automateData.Cash - cashNum, // 可提现金额
		"notCash":      automateData.NotCash,        // 待入帐金额
		"transferCash": cashNum,                     // 己提现金额，包含审核中提现
	})(OK)
}

// HandleGetServiceGoodsOrderMoney 查询服务订单可提现金额
func HandleGetServiceGoodsOrderMoney(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()
	param.UserId = userId
	param.Db = &cashlog.CashOrderLogDb{OrderType: helper.TypeNumCashOrderLogOrderTypeGoods}

	goodsData := dao.NewGoodsDao().GetGoodsOrdersToCashByUserId(param).Unwrap().(*request.OrdersCashRes)
	cashNum := dao.NewCashDao().GetOrderCashNum(param).Unwrap().(int64)

	Response(ctx)("", CodeSuccess, map[string]interface{}{
		"cash":         goodsData.Cash - cashNum, // 可提现金额
		"notCash":      goodsData.NotCash,        // 待入帐金额
		"transferCash": cashNum,                  // 己提现金额，包含审核中提现
	})(OK)
}

// HandleGetServiceRoomOrderMoney 查询服务订单可提现金额
func HandleGetServiceRoomOrderMoney(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()
	param.UserId = userId
	param.Db = &cashlog.CashOrderLogDb{OrderType: helper.TypeNumCashOrderLogOrderTypeRoom}

	roomData := dao.NewRoomDaoDao().GetRoomOrdersToCashByUserId(param).Unwrap().(*request.OrdersCashRes)
	cashNum := dao.NewCashDao().GetOrderCashNum(param).Unwrap().(int64)

	Response(ctx)("", CodeSuccess, map[string]interface{}{
		"cash":         roomData.Cash - cashNum, // 可提现金额
		"notCash":      roomData.NotCash,        // 待入帐金额
		"transferCash": cashNum,                 // 己提现金额，包含审核中提现
	})(OK)
}

// HandleGetServiceOrderMoney 查询服务订单可提现金额
func HandleGetServiceOrderMoney(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	param := &request.OrdersCashReq{}
	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()
	param.UserId = userId

	roomData := dao.NewRoomDaoDao().GetRoomOrdersToCashByUserId(param).Unwrap().(*request.OrdersCashRes)
	goodsData := dao.NewGoodsDao().GetGoodsOrdersToCashByUserId(param).Unwrap().(*request.OrdersCashRes)
	cashNum := dao.NewCashDao().GetOrderCashNum(param).Unwrap().(int64)

	Response(ctx)("", CodeSuccess, map[string]interface{}{
		"cash":         roomData.Cash + goodsData.Cash - cashNum, // 可提现金额
		"notCash":      roomData.NotCash + goodsData.NotCash,     // 待入帐金额
		"transferCash": cashNum,                                  // 己提现金额，包含审核中提现
	})(OK)
}

func HandleGetCash(c *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(c)
	dingo.ErrorIf(err).Unwrap()
	//userId := 127
	isAdmin, err := helper.GetIsAdminFromCtx(c)
	dingo.ErrorIf(err).Unwrap()

	param := &request.CashListReq{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()
	param.UserId = userId
	param.IsAdmin = int(isAdmin)
	data := dao.NewCashDao().GetQrCodeCashList(param)

	Response(c)("", CodeSuccess, ResponseList{
		PageNo:     param.PageNo,
		PageSize:   param.PageSize,
		TotalCount: data.Val().(int64),
		TotalPage:  (data.Val().(int64) + int64(param.PageSize) - 1) / int64(param.PageSize),
		Data:       data.Unwrap(),
	})(OK)
}

func HandleUpdateCash(c *gin.Context) {
	param := &cashlog.CashLogModel{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()
	transferMoneyStr := decimal.NewFromInt(param.Money).
		Mul(decimal.NewFromInt(100).Sub(decimal.NewFromInt(int64(param.TaxRate)))).Div(decimal.NewFromInt(10000)).StringFixed(2)
	d, _ := decimal.NewFromString(transferMoneyStr)
	transferMoney := d.Mul(decimal.NewFromInt(100)).IntPart()
	updateVal := map[string]interface{}{
		"transfer_money":     transferMoney,
		"transfer_money_str": transferMoneyStr,
		//"service_charge": param.ServiceCharge,
		"transfer_name": param.TransferName,
		"desc":          param.Desc,
		"state":         2,
		"verify_status": 2,
		"update_at":     dingo.Time(time.Now().Unix()),
	}
	update := dao.NewCashDao().UpdateCashLog(param.ID, updateVal).Unwrap().(bool)
	Response(c)("提现请求提交成功", CodeInsertSuccess, update)(Error)
}

// 驳回提现审请
func HandleUpdateRejectCash(c *gin.Context) {
	param := &cashlog.CashLogModel{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()
	updateVal := map[string]interface{}{
		"state":         param.State,
		"verify_status": param.State,
		"operate_note":  param.OperateNote,
		"update_at":     dingo.Time(time.Now().Unix()),
	}
	update := dao.NewCashDao().UpdateCashLog(param.ID, updateVal).Unwrap().(bool)
	Response(c)("提现请求提交成功", CodeInsertSuccess, update)(Error)
}
